Recurrence Distillation Protocol¶

In [30]:
import numpy as np
import matplotlib.pyplot as plt
import plotly.io as pio
import plotly.graph_objects as go

pio.renderers.default = "plotly_mimetype+notebook"
In [31]:
PLT_WIDTH = 1000
PLT_HEIGHT = 650
In [32]:
def F_to_werner(F):
    """ Returns werner parameter starting from the fidelity.
    
    Keyword arguments:
    F -- fidelity
    """
    return ((4*F - 1) / 3)

def output_p_dist(F_in):
    """ Returns the probability of success of the BBPSSW protocol.
    
    Keyword arguments:
    F_in -- input fidelity
    """
    p_dist_out = np.square(F_in) + 2*F_in*(1-F_in)/3 + 5*np.square(1-F_in)/9
    return p_dist_out

def output_fidelity(F_in):
    """ Returns output fidelity of BBPSSW protocol.
    
    Keyword arguments:
    F_in -- input fidelity
    """
    F_out = (np.square(F_in) + np.square(1-F_in)/9) \
            / (output_p_dist(F_in))
 
    return F_out

Output State Fidelity $F_k$ and Success Probability $p_{dist}$ in function of Fidelity $F_{k-1}$¶

In [33]:
F_0 = np.arange(0.0, 1.0, 0.01)
w_in = F_to_werner(F_0)

F_fig = go.Figure()

F_fig.add_trace(go.Scatter(x=F_0, y=output_fidelity(F_0),
                    mode='lines',
                    name="F<sub>k</sub>"))

F_fig.add_trace(go.Scatter(x=F_0, y=(output_p_dist(F_0)),
                    mode='lines',
                    name="p<sub>dist</sub>"))

F_fig.add_trace(go.Scatter(x=F_0, y=F_0,
                    mode='lines',
                    name="F<sub>k</sub>=F<sub>k-1</sub>"))

F_fig.update_layout(
    title="Effect on the fidelity of Werner states of <b>one step</b> of purification",
    xaxis_title='Input Fidelity F<sub>k-1</sub>',
    yaxis_title="Output State Fidelity F<sub>k</sub>",
    width=PLT_WIDTH,
    height=PLT_HEIGHT
)

F_fig.show()

Output Werner Parameter $w_k$ and Success Probability $p_{dist}$ in function of the Werner Parameter $w_{k-1}$¶

In [45]:
F_0 = np.arange(0.0, 1.0, 0.01)
w_in = F_to_werner(F_0)

F_fig = go.Figure()

F_fig.add_trace(go.Scatter(x=w_in, y=F_to_werner(output_fidelity(F_0)),
                    mode='lines',
                    name="w<sub>k</sub>"))

F_fig.add_trace(go.Scatter(x=w_in, y=output_p_dist(F_0),
                    mode='lines',
                    name="p<sub>dist</sub>"))

F_fig.add_trace(go.Scatter(x=w_in, y=w_in,
                    mode='lines',
                    name="w<sub>k</sub>=w<sub>k-1</sub>"))

F_fig.update_layout(
    title="Effect on the werner parameter of Werner states of <b>one step</b> of purification",
    xaxis_title='Werner Parameter w<sub>k-1</sub>',
    yaxis_title="Output Werner Parameter w<sub>k</sub>",
    width=PLT_WIDTH,
    height=PLT_HEIGHT
)

F_fig.show()

Output State Fidelity $F_k$ and Resources Needed in function of the Round Number $k$¶

Fixed $F_0 \in \left\{\frac{2}{3}, \frac{3}{4}, \frac{4}{5}\right\}$

In [44]:
target_fidelity = 0.99
F_0 = [0.66, 0.75, 0.8]

F_fig = go.Figure()
R_fig = go.Figure()

for init_F in F_0:
    fidelities = [init_F]
    pairs_needed = [1]

    while fidelities[-1] < target_fidelity:
        pairs_needed.append(2 / output_p_dist(fidelities[-1]))
        fidelities.append(output_fidelity(fidelities[-1]))

    rounds = np.arange(0, len(fidelities))
    F_fig.add_trace(go.Scatter(x=rounds, y=fidelities,
                             mode='lines',
                             name=f"F<sub>0</sub>={init_F}"))

    R_fig.add_trace(go.Scatter(x=rounds, y=np.cumprod(pairs_needed),
                            mode='lines',
                            name=f"F<sub>0</sub>={init_F}"))

F_fig.update_layout(
    title="Output State Fidelity F<sub>k</sub> in function of the round k",
    xaxis_title='Round k',
    yaxis_title="Fidelity F<sub>k</sub>",
    width=PLT_WIDTH,
    height=PLT_HEIGHT
)

R_fig.update_layout(
    title="Resource Needed in function of the round k",
    xaxis_title='Round k',
    yaxis_title="Cumulative Pairs Needed",
    width=PLT_WIDTH,
    height=PLT_HEIGHT
)

F_fig.show()
R_fig.show()